package com.wd.tw.service;

import com.alibaba.fastjson2.JSONObject;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.wd.tw.domain.aie.EventResponse;
import com.wd.tw.domain.entity.ElevatorCameraSignal;
import com.wd.tw.domain.entity.ElevatorPersonNum;
import com.wd.tw.utils.TimeUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import static com.wd.tw.constants.EleConstant.*;

/**
 * @className: EventService
 * @description: TODO 类描述
 * @author: liumingkun
 * @date: 2024/11/17
 **/

@Service
@Slf4j
public class EventService {


    @Resource
    AsyncService asyncService;

    @Resource
    ElevatorConfigService elevatorConfigService;

    @Resource
    ElevatorPersonNumService personNumService;


    /**
     * 处理商汤盒子抓拍的人员聚集
     *
     * @param eventString
     */
    public void dealEvent(String eventString) {
        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
        try {
            EventResponse response = objectMapper.readValue(eventString, EventResponse.class);
            //398为人员密集告警
            if (response.getData().getEvents_type().contains("398")) {

                String channelId = String.valueOf(response.getData().getChannel());
                String boxId = response.getData().getDevice_id();
                int crowdNum = response.getData().getEvents_attr().getCrowd_num();
                Long cameraId = elevatorConfigService.getCameraId(channelId, boxId);
                if (cameraId != null) {
                    ELE_PERSON_COUNT.put(cameraId, crowdNum);
                }
                log.info("Aie Data:" + JSONObject.toJSONString(response.getData()));
                log.info("Person Num:" + crowdNum);
                if (crowdNum >= 10) {
                    List<Integer> signalList = elevatorConfigService.getSignal(cameraId);
                    doAsyncSignal(signalList);
                }
                ElevatorPersonNum elevatorPersonNum = new ElevatorPersonNum();
                elevatorPersonNum.setCameraId(cameraId);
                elevatorPersonNum.setPersonNum(cameraId);
                personNumService.insertElevatorPersonNum(elevatorPersonNum);
            }
            //396为人员越界
            if (response.getData().getEvents_type().contains("396")) {

                String channelId = String.valueOf(response.getData().getChannel());
                String boxId = response.getData().getDevice_id();
                int inPerson = response.getData().getEvents_attr().getOver_boundary_num1();
                int outPerson = response.getData().getEvents_attr().getOver_boundary_num2();
                Long cameraId = elevatorConfigService.getCameraId(channelId, boxId);
                storeOffset(cameraId, inPerson, outPerson);
                Integer offset = ELE_PERSON_COUNT_OFFSET.get(cameraId);
                if (offset == null) {
                    offset = 0;
                }
                if (cameraId != null) {
                    ELE_PERSON_COUNT_BOUNDARY.put(cameraId, inPerson - outPerson - offset);
                }

            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public void storeOffset(Long cameraId, Integer inCount, Integer outCount) {
        Map<String, Integer> countMap = new HashMap<>();
        countMap.put("InCount", inCount);
        countMap.put("OutCount", outCount);
        ELE_PERSON_ORIGIN_OFFSET.put(cameraId, countMap);
    }


    public void edgeBoxEvent(int channelId, String boxId) {

        log.info("From EdgeBox ChannelId:" + channelId + "  BoxId:" + boxId);

        Long cameraId = elevatorConfigService.getCameraId(String.valueOf(channelId), boxId);
        List<ElevatorCameraSignal> signalList = elevatorConfigService.getSignalInfo(cameraId);

        if (signalList == null || signalList.size() == 0) {
            return;
        }

        List<Integer> speList = signalList.stream().filter(item -> item.getSignalType().intValue() == 1)
                .map(signal -> signal.getSignalId().intValue()).collect(Collectors.toList());
        //发送专用信号
        if (speList.size() > 0) {
            doAsyncSignal(speList);
        }

        List<Integer> callList = signalList.stream().filter(item -> item.getSignalType().intValue() == 2).map(signal -> signal.getSignalId().intValue()).collect(Collectors.toList());
        //发送呼梯信号
        if (callList.size() > 0) {
            syncSignal(callList);
        }
        if (speList.size() == 0 && callList.size() == 0) {
            log.info("EdgeBox ChannelId:" + channelId + "  BoxId:" + boxId + "  signal is null");
        }
    }

    //电梯专用，需要25秒后关闭
    public void doAsyncSignal(List<Integer> signalList) {
        for (int i = 0; i < signalList.size(); i++) {
            Integer signal = signalList.get(i);
            Boolean aBoolean = ELE_STATUS.get(signal);
            log.info("CallSpecialBegin" + signal);
            if (aBoolean == null || aBoolean == false) {
                asyncService.asyncSpecialSignal(signal);
            }
            log.info("CallSpecialSuccess" + signal);
        }
    }


    public void syncSignal(List<Integer> signalList) {
        for (int i = 0; i < signalList.size(); i++) {
            Integer signal = signalList.get(i);
            log.info("CallAsyncBegin" + signal);
            if (needToSendSignal(signal)) {
                asyncService.asyncCallSignal(signal);
            }
            log.info("CallAsyncSuccess" + signal);
        }
    }

    public boolean needToSendSignal(Integer signal) {
        Long aLong = ELE_TIME.get(signal);
        Long curTime = TimeUtils.getCurrentTime();
        if (aLong == null) {
            ELE_TIME.put(signal, curTime);
            return true;
        }
        if (curTime - aLong >= 10) {
            ELE_TIME.put(signal, curTime);
            return true;
        } else {
            log.info("Frequency too high:" + signal);
            return false;
        }
    }

    public static void main(String[] args) {
        Map<Long, Integer> map = new HashMap<>();
        int a = 10;
        System.out.println(a - map.get(1L));
    }
}
